using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;

namespace TheWorldOfKongfuEasyMod;

[HarmonyPatch(typeof(SharedData ))]
[HarmonyPatch(MethodType.Constructor)]
public class Patch_SharedData_RefreshAllMine
{
    public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
    {
        if (!Main.Setting._012isRefreshAllMine.Value)
            return instructions;
        var codeMatcher = new CodeMatcher(instructions, generator);
        
        codeMatcher.MatchForward(false, new CodeMatch(OpCodes.Stfld, typeof(SharedData)
            .GetField("MaxMineNumInOneMap", BindingFlags.Instance| BindingFlags.Public | BindingFlags.NonPublic))
        );
        if (!codeMatcher.IsValid)
        {
            throw new InvalidOperationException("Can't find MaxMineNumInOneMap");
        }

        codeMatcher.Advance(-1);
        codeMatcher.RemoveInstruction()
            .InsertAndAdvance(
                new CodeInstruction(OpCodes.Ldc_I4_5)
            );
        return codeMatcher.Instructions();
    }
}

[HarmonyPatch(typeof(MapController ))]
[HarmonyPatch("DoAutoAction")]
public class Patch_MapController_MineNum
{
    public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
    {
        var codeMatcher = new CodeMatcher(instructions, generator);

        codeMatcher.MatchForward(false,
            new CodeMatch(OpCodes.Br),
            new CodeMatch(OpCodes.Ldloc_0),
            new CodeMatch(OpCodes.Ldfld),
            new CodeMatch(OpCodes.Ldc_I4_1),
            new CodeMatch(OpCodes.Ldelem_Ref),
            new CodeMatch(OpCodes.Ldstr,"MINE"),
            new CodeMatch(OpCodes.Call,typeof(string).GetMethod("op_Equality", 
                BindingFlags.Static| BindingFlags.Public , null ,new Type[]{typeof(string),typeof(string)},null)),
            new CodeMatch(OpCodes.Brfalse)
            );
        if (!codeMatcher.IsValid)
        {
            throw new InvalidOperationException("Can't find if(act[1]==\"MINE\")");
        }   
        codeMatcher.MatchForward(true,
            new CodeMatch(OpCodes.Ldloc_S),
            new CodeMatch(OpCodes.Ldc_I4_1),
            new CodeMatch(OpCodes.Add),
            new CodeMatch(OpCodes.Call, typeof(Random).GetMethod("Range",
                BindingFlags.Static| BindingFlags.Public , null ,new Type[]{typeof(int),typeof(int)},null))
            
        );
        if (!codeMatcher.IsValid)
        {
            throw new InvalidOperationException("Can't find Random.Range");
        }

        codeMatcher.Advance(-2);
        codeMatcher.RemoveInstruction()
            .InsertAndAdvance(
                new CodeInstruction(OpCodes.Ldc_I4_S, Main.Setting._013stoneNumMin.Value),
                new CodeInstruction(OpCodes.Ldc_I4_S, Main.Setting._014stoneNumMax.Value)
            );
        return codeMatcher.Instructions();
    }
}